package com.kc.gb.device.plugins.slant.service.impl;

import com.kc.gb.device.common.dto.I18NException;
import com.kc.gb.device.common.enums.ErrorCode;
import com.kc.gb.device.common.properties.DeviceProperties;
import com.kc.gb.device.plugins.slant.service.SlantHardwareService;
import com.kc.gb.device.plugins.slant.utils.SlantUtils;
import com.kc.gb.feign.slant.support.SlantCommand;
import com.kc.gb.feign.slant.support.SlantCommandType;
import com.kc.gb.feign.slant.support.StationPointLayout;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.List;

@Slf4j
@Service
public class SlantHardwareServiceImpl implements SlantHardwareService {

    @Resource
    DeviceProperties deviceProperties;

    private static DatagramSocket socket = null;

    @Override
    public DatagramSocket connect(String ip, int port) throws IOException {
        if(socket==null){
            socket = new DatagramSocket(port,InetAddress.getByName(ip));
        }
        return socket;
    }

    @Override
    public void consumeCommands(List<SlantCommand> commands, boolean isDebugMode){
        if(CollectionUtils.isEmpty(commands)){
            return;
        }
        Throwable throwable = null;
        for (int i = 0; i < CollectionUtils.emptyIfNull(commands).size(); i++) {
            try {
                send2Hardware(isDebugMode,commands.get(i));
            } catch (Throwable e) {
                throwable = e;
            }
        }
        if(throwable != null){
            throw new RuntimeException(throwable.getMessage());
        }
    }

    void send2Hardware(boolean isDebugMode,SlantCommand command) throws IOException {
        String stationCode = command.getStationCode();
        StationPointLayout position = command.getPosition();
        SlantCommandType type = command.getType();
        String commandValue = SlantUtils.build2SlantDeviceCommand(stationCode,position,type);
        String ip = deviceProperties.getDeviceSlantIP();
        int port = deviceProperties.getDeviceSlantPort();
        send2UDP(socket,commandValue);
    }

    void send2UDP(DatagramSocket udp,String command) throws IOException {
        if(udp==null){
            throw new I18NException(ErrorCode.HARDWARE_CONNECT_ERROR);
        }
        String ip = udp.getInetAddress().getHostAddress();
        int port = udp.getPort();
        byte[] bytes = SlantUtils.hexToBytes(command);
        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getByName(ip), port);
        log.info("socket.send slantDeviceIp:{}, slantDevicePort:{},command:{}", ip, port, command);
        udp.send(datagramPacket);
    }
}
